<?php


namespace app\common\helper;

use app\common\model\User;
use GuzzleHttp\Client;
use think\exception\HttpResponseException;
use think\helper\Str;

class WxHelper
{
    protected $appid;
    protected $url;
    protected $secret;
    protected $session_key;
    protected $openid;
    protected $client;
    protected $mch_id;
    public function __construct()
    {
        $Config = cache('config');
        $this->appid = $Config['wx_appid'];
        $this->secret = $Config['wx_secret'];
        $this->mch_id = $Config['wx_mchid'];
        $this->url = "https://api.weixin.qq.com/sns/jscode2session?";
        $this->client = new Client();
    }

    // 获取手机号
    public function getPhoneNumber($code)
    {
        $access_token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={$access_token}";
        $result = $this->client->post($url,['json'=>['code'=>$code]])->getBody();
        $result = json_decode($result,true);
        if (!empty($result['phone_info'])) {
            return $result['phone_info']['purePhoneNumber'];
        } else {
            $response = json(['code'=>0,'msg'=>'获取手机号失败']);
            throw new HttpResponseException($response);
        }
    }

    public function decryptData($params)
    {
        $pc = new WxBizDataCrypt($this->appid,$this->session_key);
        $result =  $pc->decryptData($params['encryptedData'],$params['iv'],$data);
        if ($result == 0) {
            return json_decode($data,true);
        } else {
            return $result;
        }
    }

    public function code2Session($code)
    {
        $param['appid'] = $this->appid;
        $param['secret'] = $this->secret;
        $param['js_code'] = $code;
        $param['grant_type'] = "authorization_code";
        $client = new Client();
        $result = $client->get($this->url . http_build_query($param))->getBody();
        $result = json_decode($result,true);
        if (!empty($result['session_key'])) {
            $this->openid = $result['openid'];
            $this->session_key = $result['session_key'];
        } else {
            $response = json(['code'=>0,'msg'=>'获取sessionkey失败']);
            throw new HttpResponseException($response);
        }
        return $this;
    }

    public function setSessionKey($key) {
        if ($key) {
            $this->session_key = $key;
        }
        return $this;
    }

    public function setSecret($secret) {
        $this->secret = $secret;
        return $this;
    }

    public function getOpenid(){
        return $this->openid;
    }

    public function getAppid()
    {
        return $this->appid;
    }


    // 公众号授权 获取code
    public function getScopeCodeUrl()
    {
        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?";
        $param = [
            "appid" => $this->appid,
            "redirect_uri" => app()->request->domain() . "/" . url("Auth/auth"),
            "response_type" => "code",
            "scope" => "snsapi_userinfo",
        ];
        return $url . http_build_query($param) . "#wechat_redirect";
    }

    // 公众号 code to access_token
    public function codeToAccessToken($code)
    {
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?";
        $param = [
            "appid" => $this->appid,
            "secret" => $this->secret,
            "code" => $code,
            "grant_type" => "authorization_code",
        ];
        $result = $this->client->get($url . http_build_query($param))->getBody()->getContents();
        $result = json_decode($result,true);
        if (empty($result['openid'])) {
            throw new HttpResponseException(json(['code'=>0,"msg"=>"获取openid失败"]));
        }
        $this->openid = $result['openid'];
        $this->session_key = $result['access_token'];
        return $this;
    }

    // 获取用户信息
    public function getUserInfo()
    {
        $url = "https://api.weixin.qq.com/sns/userinfo?";
        $param = [
            "access_token" => $this->session_key,
            "openid" => $this->openid,
            "lang" => "zh_CN",
        ];
        $result = $this->client->get($url . http_build_query($param))->getBody()->getContents();
        $result = json_decode($result,true);
        if (empty($result['openid'])) {
            throw new HttpResponseException(json(['code'=>0,"msg"=>"获取userinfo失败"]));
        }
        return $result;
    }

    // 公众号获取 access_token  小程序都可用
    public function getAccessToken()
    {
        $access_token = cache('access_token');
        if (empty($access_token)) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appid}&secret={$this->secret}";
            $result = $this->client->get($url)->getBody()->getContents();
            $result = json_decode($result,true);
            if (!empty($result['access_token'])) {
                cache('access_token',$result['access_token'],7000);
                $access_token = $result['access_token'];
            } else {
                throw new HttpResponseException(json(['code'=>0,"msg"=>"获取token失败"]));
            }
        }
        return $access_token;
    }

    // 公众号获取票据
    public function getTicket()
    {
        $ticket = cache('ticket');
        if (empty($ticket)) {
            $access_token = $this->getAccessToken();
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=jsapi";
            $result = $this->client->get($url)->getBody()->getContents();
            $result = json_decode($result,true);
            if (!empty($result['ticket'])) {
                cache('ticket',$result['ticket'],7000);
                $ticket = $result['ticket'];
            } else {
                throw new HttpResponseException(json(['code'=>0,"msg"=>"获取ticket失败"]));
            }
        }
        return $ticket;
    }

    // 公众号签名
    public function makeSign($url)
    {
        $time = time();
        $noncestr = Str::random(10);
        $param = [
            "jsapi_ticket" => $this->getTicket(),
            "noncestr" => $noncestr,
            "timestamp" => $time,
            "url" => $url
        ];
        $str = "";
        foreach ($param as $key => $value) {
            $str .= $key . "=" . $value . "&";
        }
        $str = substr($str,0,strlen($str) - 1);
        return [
            "appId" => $this->appid,
            "timestamp" =>  $time,
            "nonceStr" => $noncestr,
            "signature" => sha1($str),
            "url" => $url,
            "str" => $str
        ];
    }

    // 同步发货信息到小程序后台
    public function sendOrderToWx($order)
    {
        $user = User::where(['user_id'=>$order['user_id']])->find();
        $url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" . $this->getAccessToken();
        $shipping_list = [];
        foreach ($order['item'] as $key => $item) {
            $shipping_list[0] = [
                "item_desc" => $item['goods_title'] . "*" . $item['goods_num'],
            ];
        }
        $data = [
            "order_key" => [
                "order_number_type" => 1,
                "mchid" => $this->mch_id,
                "out_trade_no" => $order['order_sn']
            ],
            "logistics_type" => 4,
            "delivery_mode" => "UNIFIED_DELIVERY",
            "shipping_list" => $shipping_list,
            "upload_time" => date(DATE_RFC3339),
            "payer" => [
                "openid" => $user['openid'],
            ]
        ];
        $result = $this->client->post($url, ['body' => json_encode($data, JSON_UNESCAPED_UNICODE)]);
        $result = json_decode($result->getBody()->getContents(),true);
        if ($result['errcode'] == 0) {
            return $result;
        } else {
            file_put_contents('sendToWx.txt',$result['errmsg']  . "-" . $result['errcode'] ."--order\r\n");
            return $result;
        }
    }
}